using Blazorise.Bootstrap5;
using Blazorise.Icons.FontAwesome;

using HealthChecks.UI.Client;

using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;

using Volo.Abp;
using Volo.Abp.Account.Web;
using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme;
using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.Theming.Routing;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.FeatureManagement.Blazor.Server;
using Volo.Abp.Identity.Blazor.Server;
using Volo.Abp.Modularity;
using Volo.Abp.SettingManagement.Blazor.Server;
using Volo.Abp.Swashbuckle;
using Volo.Abp.TenantManagement.Blazor.Server;
using Volo.Abp.UI.Navigation;

using WL.Think.Abp;
using WL.Think.Abp.Components;
using WL.Think.Abp.Localization;
using WL.Think.Abp.OpenIddict.Blazor;
using WL.Think.Sample.Blazor.Menus;
using WL.Think.Sample.Domain;

namespace WL.Think.Sample.Blazor;

[DependsOn(
    typeof(SampleAppModule),
    typeof(SampleDataModule),
    typeof(SampleApiModule),
    typeof(AbpAutofacModule),
    typeof(AbpSwashbuckleModule),
    typeof(AbpIdentityBlazorServerModule),
    typeof(AbpTenantManagementBlazorServerModule),
    typeof(AbpAccountWebOpenIddictModule),
    typeof(AbpAspNetCoreComponentsServerLeptonXLiteThemeModule),
    typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule),
    typeof(AbpAspNetCoreSerilogModule),
    typeof(AbpFeatureManagementBlazorServerModule),
    typeof(AbpSettingManagementBlazorServerModule),
    typeof(ThinkAbpOpenIddictBlazorModule)
   )]
public class SampleBlazorModule : ThinkAbpAppHostModule
{
    protected override void PreConfigureDataAnnotationsLocalization(ServiceConfigurationContext context)
    {
        context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
        {
            options.AddAssemblyResource(
                typeof(ThinkResource),
                typeof(SampleDomainModule).Assembly,
                typeof(SampleSharedModule).Assembly,
                typeof(SampleAppModule).Assembly,
                typeof(SampleIAppModule).Assembly,
                typeof(SampleBlazorModule).Assembly
            );
        });
    }

    protected override void PreConfigureWebComponents(ServiceConfigurationContext context)
    {
        PreConfigure<AbpAspNetCoreComponentsWebOptions>(options =>
        {
            options.IsBlazorWebApp = true;
        });
    }


    protected override void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
    {
        // var hostingEnvironment = context.Services.GetHostingEnvironment();
        // if (hostingEnvironment.IsDevelopment())
        // {
        //     Configure<AbpVirtualFileSystemOptions>(options =>
        //     {
        //         options.FileSets.ReplaceEmbeddedByPhysical<SampleSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WL.Think.Sample.Shared"));
        //         options.FileSets.ReplaceEmbeddedByPhysical<SampleDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WL.Think.Sample.Domain"));
        //         options.FileSets.ReplaceEmbeddedByPhysical<SampleIAppModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WL.Think.Sample.IApplication"));
        //         options.FileSets.ReplaceEmbeddedByPhysical<SampleAppModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}WL.Think.Sample.Application"));
        //         options.FileSets.ReplaceEmbeddedByPhysical<SampleBlazorModule>(hostingEnvironment.ContentRootPath);
        //     });
        // }
    }

    protected override void ConfigureAutoMapper(ServiceConfigurationContext context)
    {
        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<SampleBlazorModule>();
        });
    }

    protected override void ConfigureMenu(ServiceConfigurationContext context)
    {
        Configure<AbpNavigationOptions>(options =>
        {
            options.MenuContributors.Add(new SampleMenuContributor());
        });
    }
    

    protected override void ConfigureRouter(ServiceConfigurationContext context)
    {
        Configure<AbpRouterOptions>(options =>
        {
            options.AppAssembly = typeof(SampleBlazorModule).Assembly;
        });
    }

    protected override void ConfigureWebComponents(ServiceConfigurationContext context)
    {
        context.Services.AddRazorComponents().AddInteractiveServerComponents();
        context.Services.AddBootstrap5Providers().AddFontAwesomeIcons();
    }

    protected override void ConfigureBundles(ServiceConfigurationContext context)
    {
        Configure<AbpBundlingOptions>(options =>
        {
            // MVC UI
            options.StyleBundles.Configure(
                LeptonXLiteThemeBundles.Styles.Global,
                bundle =>
                {
                    bundle.AddFiles("/global-styles.css");
                }
            );

            options.ScriptBundles.Configure(
                LeptonXLiteThemeBundles.Scripts.Global,
                bundle =>
                {
                    bundle.AddFiles("/global-scripts.js");
                }
            );

            // Blazor UI
            options.StyleBundles.Configure(
                BlazorLeptonXLiteThemeBundles.Styles.Global,
                bundle =>
                {
                    bundle.AddFiles("/global-styles.css");
                }
            );
        });
    }

    protected override void ConfigureHealthChecks(ServiceConfigurationContext context)
    {
        base.ConfigureHealthChecks(context);
        context.Services.Configure<AbpEndpointRouterOptions>(options =>
        {
            options.EndpointConfigureActions.Add(endpointContext =>
            {
                endpointContext.Endpoints.MapHealthChecks(
                    new PathString("/health-status"),
                    new HealthCheckOptions
                    {
                        Predicate = _ => true,
                        ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse,
                        AllowCachingResponses = false,
                    });
            });
        });

        var configuration = context.Services.GetConfiguration();
        var healthCheckUrl = configuration.GetValue("App:HealthCheckUrl", "/health-status");
        var healthChecksUiBuilder = context.Services.AddHealthChecksUI(settings =>
        {
            var healthCheckInterval = configuration.GetValue("App:HealthCheckInterval", 300);
            settings.SetEvaluationTimeInSeconds(healthCheckInterval);
            settings.AddHealthCheckEndpoint("Application Health Status", healthCheckUrl);
        });

        healthChecksUiBuilder.AddInMemoryStorage();
        context.Services.Configure<AbpEndpointRouterOptions>(routerOptions =>
        {
            routerOptions.EndpointConfigureActions.Add(endpointContext =>
            {
                endpointContext.Endpoints.MapHealthChecksUI(opts =>
                {
                    opts.UIPath = "/health-ui";
                    opts.ApiPath = "/health-api";
                });
            });
        });
    }

    protected override void MapEndpoints(IEndpointRouteBuilder builder)
    {
        builder.MapRazorComponents<App>()
                .AddInteractiveServerRenderMode()
                .AddAdditionalAssemblies(builder.ServiceProvider.GetRequiredService<IOptions<AbpRouterOptions>>().Value.AdditionalAssemblies.ToArray());
    }
}
